﻿/*
SINACOR - BMF&Bovespa
Arquivo: ReaberturaMovimentoBolsa.cs
Criado em: 17-mar-2010 16:38:02
Arquiteto Responsável: p-Wgeneroso
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Sinacor.Infra.Core.ProcessManager.Server;
using Sinacor.Infra.Common.Exceptions;
using Sinacor.Infra.Service.ExceptionHandling;
using PSE.ProcessManager.Common.Process;
using PSE.ProcessManager.Server.Process.Security;
using Sinacor.Infra.Core.ProcessManager.Server.Security;
using Sinacor.Infra.Common.Validation;
using Sinacor.Infra.Service.Validation;


namespace Sinacor.Process.Bovespa.ControleMovimentoBolsa.Server.ProcessLogic
{
    public class ReaberturaMovimentoBolsa : BaseProcessLogic
    {


        #region Campos
        private int _erroContasCorrentesFechado = 109683;
        private int _erroContasCorrentesNaoInstalado = 109682;
        private int _erroCustodiaFechado = 109685;
        private int _erroCustodiaNaoInstalado = 109684;
        private int _erroMovimentoAberto = 109681;
        private int _erroNaoEsperado = 109686;
        private int _erroObjetoNulo = 109680;
        private int _erroSemPermissaoAcesso = 109678;
        private ResourceAccess.ReaberturaMovimentoBolsa _resourceAccessReaberturaMovimentoBolsa;
        #endregion

        #region Propriedades

        public int ErroContasCorrentesFechado
        {
            get { return _erroContasCorrentesFechado; }
            set { _erroContasCorrentesFechado = value; }
        }


        public int ErroContasCorrentesNaoInstalado
        {
            get { return _erroContasCorrentesNaoInstalado; }
            set { _erroContasCorrentesNaoInstalado = value; }
        }


        public int ErroCustodiaFechado
        {
            get { return _erroCustodiaFechado; }
            set { _erroCustodiaFechado = value; }
        }


        public int ErroCustodiaNaoInstalado
        {
            get { return _erroCustodiaNaoInstalado; }
            set { _erroCustodiaNaoInstalado = value; }
        }


        public int ErroMovimentoAberto
        {
            get { return _erroMovimentoAberto; }
            set { _erroMovimentoAberto = value; }
        }


        public int ErroNaoEsperado
        {
            get { return _erroNaoEsperado; }
            set { _erroNaoEsperado = value; }
        }


        public int ErroObjetoNulo
        {
            get { return _erroObjetoNulo; }
            set { _erroObjetoNulo = value; }
        }


        public int ErroSemPermissaoAcesso
        {
            get { return _erroSemPermissaoAcesso; }
            set { _erroSemPermissaoAcesso = value; }
        }
        #endregion


        #region Métodos
        /// <summary>
        /// Reabre o movimento bolsas
        /// </summary>
        /// <param name="entity"></param>
        public void ReabrirMovimento(ProcessEntity.Parameter.FiltroControleMovimento entity)
        {
            ResourceAccess.AberturaMovimentoBolsa  _resourceAccessAberturaMovimentoBolsa = new Sinacor.Process.Bovespa.ControleMovimentoBolsa.Server.ResourceAccess.AberturaMovimentoBolsa();
            ResourceAccess.ReaberturaMovimentoBolsa _resourceAccessReaberturaMovimentoBolsa = new Sinacor.Process.Bovespa.ControleMovimentoBolsa.Server.ResourceAccess.ReaberturaMovimentoBolsa();
            Communication.ParametroBolsa _communicationParametroBolsa = new Sinacor.Process.Bovespa.ControleMovimentoBolsa.Server.Communication.ParametroBolsa();
            ProcessEntity.Resultado resultado = new Sinacor.Process.Bovespa.ControleMovimentoBolsa.ProcessEntity.Resultado();
            
            if (entity != null)
            {
                if (VerificarPermissaoAcesso())
                {

                       SinacorValidation validation = new SinacorValidation();
                       validation.Validate<ProcessEntity.Parameter.FiltroControleMovimento>(entity);
                       validation.Validate();
                       validation = null;

                    if (VerificarMovimentoFechado())
                    {
                        ProcessEntity.ParametroBolsa _parametroBolsa = new Sinacor.Process.Bovespa.ControleMovimentoBolsa.ProcessEntity.ParametroBolsa();
                        _parametroBolsa = _communicationParametroBolsa.ObterParametroBolsa();

                        if (_parametroBolsa.IntegraContasCorrentes)
                        {
                            this.ValidarContasCorrentes(entity);                        
                        }
                        if (_parametroBolsa.IntegraCustodia)
                        {
                            this.ValidarCustodia(entity);
                        }
                        if (this._resourceAccessReaberturaMovimentoBolsa == null)
                            this._resourceAccessReaberturaMovimentoBolsa = new Sinacor.Process.Bovespa.ControleMovimentoBolsa.Server.ResourceAccess.ReaberturaMovimentoBolsa();
                       resultado = this._resourceAccessReaberturaMovimentoBolsa.ReabrirMovimento();
                       if (resultado.Sucesso)
                       {
                           _resourceAccessAberturaMovimentoBolsa.AtualizarMovimentoAberto();
                       }
                       else if (resultado.CodigoErro == -1)
                       {
                           throw new BusinessException(ErroNaoEsperado);
                       }
                       else
                       {
                           this.TratarExcecoes(resultado);
                       }
                    }
                    else
                    {
                        throw new BusinessException(ErroMovimentoAberto);
                    }
                }
                else
                {
                    throw new BusinessException(ErroSemPermissaoAcesso);
                }
            }
            else
            {
                throw new BusinessException(ErroObjetoNulo);
            }

            //Verificar diagrama de atividades
            //ReaberturaMovimentoBolsa.
            //ReabrirMovimento()
            
        }

        /// <summary>
        /// Trata as exceções geradas na execução da abertura.
        /// </summary>
        /// <param name="entity"></param>
        private void TratarExcecoes(ProcessEntity.Resultado entity)
        {
            if (entity != null)
            {
                if (entity.Argumentos != null)
                {
                    ErrorMessage.ConvertXmlArgumentsToParameters(entity.Argumentos);
                    throw new BusinessException(ErroNaoEsperado);
                }
                else
                {
                    throw new BusinessException(ErroNaoEsperado);
                }

            }

            //1. Verificar se o resultado enviado no
            //parametro possui argumentos
            //
            //Se a propriedade "Argumentos" da
            //entidade enviada não estiver nula ou
            //vazia
            //
            //1.1. Existem argumentos, então consumir
            //o método Sinacor.Infra.Service.
            //ErrorMessage().
            //ConvertXmlArgumentsToParameters(entity.
            //Argumentos)
            //1.2. Gerar uma BusinessException
            //informando o codigo do erro e os
            //argumentos obtidos na ação anterior.
            //
            //SeNão
            //
            //2.1. Não existem argumentos, então
            //gerar um BusinessException informando o
            //codigo do erro.
            //
            //FimSe



        }

        /// <summary>
        /// Efetua validação de integração com o módulo de Contas Correntes
        /// </summary>
        /// <param name="entity"></param>
        private void ValidarContasCorrentes(ProcessEntity.Parameter.FiltroControleMovimento entity)
        {
            if (this.VerificarModuloContasCorrentesInstalado())
            {
                _resourceAccessReaberturaMovimentoBolsa = new Sinacor.Process.Bovespa.ControleMovimentoBolsa.Server.ResourceAccess.ReaberturaMovimentoBolsa();
                if (_resourceAccessReaberturaMovimentoBolsa.VerificarMovimentoCCFechado(entity))
                {
                    throw new BusinessException(ErroContasCorrentesFechado);
                }
            }
            else
            {
                throw new BusinessException(ErroContasCorrentesNaoInstalado);
            }

            //Verificar diagrama de atividades
            //ReaberturaMovimentoBolsa.
            //ValidarContasCorrentes()          
        }

        /// <summary>
        /// Efetua validação de integração com o módulo de Custódia
        /// </summary>
        /// <param name="entity"></param>
        private void ValidarCustodia(ProcessEntity.Parameter.FiltroControleMovimento entity)
        {
            if (this.VerificarModuloCustodiaInstalado())
            {
                _resourceAccessReaberturaMovimentoBolsa = new Sinacor.Process.Bovespa.ControleMovimentoBolsa.Server.ResourceAccess.ReaberturaMovimentoBolsa();
                if (_resourceAccessReaberturaMovimentoBolsa.VerificarMovimentoCustodiaFechado(entity))
                {
                    throw new BusinessException(ErroCustodiaFechado);
                }
            }
            //Verificar diagrama de atividades
            //ReaberturaMovimento.ValidarCustodia()            
        }

        /// <summary>
        /// Verifica se o módulo de Contas Correntes está instalado.
        /// </summary>
        private bool VerificarModuloContasCorrentesInstalado()
        {
            if (!(new Communication.Acesso()).VerificarSistemaInstalado("CCO"))
            {
                throw new BusinessException(ErroContasCorrentesNaoInstalado);
            }
            return true;
            //Checar se o usuário possui instalado o
            //modulo de Ordens Bovespa, consumindo o
            //método "VerificarSistemaInstalado", do
            //AuthorizationContext do processo em
            //execução, passando como parametro "CCO".

           
            
        }

        /// <summary>
        /// Verifica se o módulo de Custódia está instalado.
        /// </summary>
        private bool VerificarModuloCustodiaInstalado()
        {
            if (!(new Communication.Acesso()).VerificarSistemaInstalado("CF"))
            {
                throw new BusinessException(ErroCustodiaNaoInstalado);
            }

            return true;
            //Checar se o usuário possui instalado o
            //modulo de Ordens Bovespa, consumindo o
            //método "VerificarSistemaInstalado", do
            //AuthorizationContext do processo em
            //execução, passando como parametro "CF".


            
        }

        /// <summary>
        /// Verifica se o movimento de bolsas está fechado.
        /// </summary>
        private bool VerificarMovimentoFechado()
        {

            ProcessEntity.InformacoesMovimento informacoesMovimento = new Sinacor.Process.Bovespa.ControleMovimentoBolsa.ProcessEntity.InformacoesMovimento();
            Communication.ControleMovimentoBolsa controleMovimentoBolsa = new Sinacor.Process.Bovespa.ControleMovimentoBolsa.Server.Communication.ControleMovimentoBolsa();
            informacoesMovimento = controleMovimentoBolsa.ObterInformacoesMovimento(new ProcessEntity.DataMovimento());

            if (informacoesMovimento.EstadoMovimento == ProcessEntity.Enum.TipoMovimento.Fechado || informacoesMovimento.EstadoMovimento == ProcessEntity.Enum.TipoMovimento.AtualizandoVersao)
            {
                return true;
            }
            else
            {
                return false;
            }


            //1. Obter informações do movimento,
            //consumindo o método Communication.
            //ControleMovimentoBolsas.
            //ObterInformacoesMovimento() informando
            //no parametro a entidade vazia.
            //
            //Exemplo:
            //informacoesMovimento = Communication.
            //ControleMovimentoBolsas.
            //ObterInformacoesMovimento(new
            //ProcessEntity.DataMovimento());
            //
            //2. Verificar se o estado do movimento
            //está fechado ou atualizando versão.
            //
            //Se informacoesMovimento.EstadoMovimento
            //igual a TipoMovimento.Fechado .ou.
            //informacoesMovimento.EstadoMovimento
            //igual a TipoMovimento.AtualizandoVersao
            // Retornar verdadeiro.
            //SeNao
            // Retornar falso.
            //FimSe


            
        }

        /// <summary>
        /// Verifica se o usuário possui permissão de acesso para reabrir o movimento bolsa.
        /// 
        /// </summary>
        private bool VerificarPermissaoAcesso()
        {
            if (!AuthorizationContext<SinacorAuthorizationContext>.Current.CheckUserAccess("BREABR", "BOL"))
            {
                throw new BusinessException(ErroSemPermissaoAcesso);
            }
            return true;
            //Checar se o usuário logado possui
            //acesso à função "BREABR"
        }
        #endregion
    }

}